package com.jvm.simulation.hotspot.runtime;

import cn.hutool.core.util.ObjectUtil;
import com.jvm.simulation.hotspot.ByteUtil;
import com.jvm.simulation.hotspot.bytecode.BasicType;
import com.jvm.simulation.hotspot.descriptor.DescriptorInfo;
import lombok.Data;

import java.util.Arrays;

@Data
public class StackValue {

    private int type;

    /**
     * 数据存储在这里的情况：
     *  1、float
     *  2、long
     */
    private byte[] data;

    /**
     * 数据
     */
    private int val;

    private Object object;

    public Object getObject(DescriptorInfo info) {
        return ObjectUtil.isAllEmpty(object) ? ObjectUtil.isAllEmpty(data) ? val : data : object;
    }


    public StackValue(int type, Object val) {
        this.type = type;
        if (val.getClass().equals(Integer.class)) {
            this.val = (int)val;
        }else if (val.getClass().equals(Float.class)){
            this.data = ByteUtil.floatToByte((Float)val);
        }else if (val.getClass().equals(Long.class)){
            this.data = ByteUtil.longToBytes((Long)val);
        }else if (val.getClass().equals(String.class)){
            this.data = ((String)val).getBytes();
        }else{
            this.object = val;
        }
    }

    public Object getData() {
        switch (type) {
            case BasicType.T_FLOAT:
                return ByteUtil.byteToFloat(data);
            case BasicType.T_LONG:
                return ByteUtil.bytesToLong(data);
            case BasicType.T_INT:
                return val;
                default:new String(data);
        }

        return null;
    }

    @Override
    public String toString() {
        return "StackValue{" +
                "type=" + type +
                ", data=" + Arrays.toString(data) +
                ", val=" + val +
                ", object=" + object +
                '}';
    }
}